﻿/*! \file strutil.h
    \brief 字符串相关工具函数

    字符串相关的工具函数全部放置在这里,但是和国际化相关的函数并不在此
*/

#pragma once
#include <list>
#include <string>
#include <vector>
#include "base/platform.h"

namespace acutil{
  namespace string{

    /*!
        \brief      将\a string_list 内所有字符串以\a seperator 为间隔串联起来
        \param[in]  string_list 原始的字符串列表
        \param[in]  seperator 连接字符串
        \return     连接生成的字符串
    */
    template <typename CharT, typename StringContainer>
    std::basic_string<CharT> Join(const StringContainer& string_list, const std::basic_string<CharT>& seperator);

    /*!
        \brief      将字符串\a s 中所有字符按照\a (A-Z)=>(a-z) 的对应关系全部转化为小写
        \param[in]  s 原始字符串
        \return     转化生成的小写字符串
        \see        ToLower, Upper, ToUpper
    */
    template <typename CharT>
    std::basic_string<CharT> Lower(const std::basic_string<CharT>& s);

    /*!
        \brief      将字符串\a s 中所有字符按照\a (a-z)=>(A-Z) 的对应关系全部转化为大写
        \param[in]  s 原始字符串
        \return     转化生成的大写字符串
        \see        ToUpper, Lower, ToLower
    */
    template <typename CharT>
    std::basic_string<CharT> Upper(const std::basic_string<CharT>& s);

    /*!
        \brief          与 Lower() 功能相类似,只是 ToLower() 是对字符串进行原地修改
        \param[in,out]  s 原始字符串/转化后的小写字符串
        \see            ToUpper, Lower, Upper
    */
    template <typename CharT>
    void ToLower(std::basic_string<CharT>& s);

    /*!
        \brief          与 Upper() 功能相类似,只是 ToUpper() 是对字符串进行原地修改
        \param[in,out]  s 原始字符串/转化后的大写字符串
        \see            ToLower, Lower, Upper
    */
    template <typename CharT>
    void ToUpper(std::basic_string<CharT>& s);

    /*!
        \brief          删除\a s 首部多余的字符,多余字符列表由\a trim_chars 指定
        \param[in,out]  s 原始字符串/Trim后字符串
        \param[in]      trim_chars 需去除的字符列表
        \see            TrimEnd, TrimStart_If, TrimEnd_If, Trim, Trim_If
    */
    template <typename CharT>
    void TrimStart(std::basic_string<CharT>& s, const std::basic_string<CharT>& trim_chars);

    /*!
        \brief          删除\a s 尾部多余的字符,多余字符列表由\a trim_chars 指定
        \param[in,out]  s 原始字符串/Trim后字符串
        \param[in]      trim_chars 需去除的字符列表
        \see            TrimStart, TrimStart_If, TrimEnd_If, Trim, Trim_If
    */
    template <typename CharT>
    void TrimEnd(std::basic_string<CharT>& s, const std::basic_string<CharT>& trim_chars);

    /*!
        \brief          删除\a s 首部与尾部多余的字符,多余字符列表由\a trim_chars 指定
        \param[in,out]  s 原始字符串/Trim后字符串
        \param[in]      trim_chars 需去除的字符列表
        \see            TrimStart, TrimEnd, TrimStart_If, TrimEnd_If, Trim_If
    */
    template <typename CharT>
    void Trim(std::basic_string<CharT>& s, const std::basic_string<CharT>& trim_chars);

    /*!
        \brief          Trim(std::basic_string<CharT>&, const CharT*) 的特殊版本,去除\a s 首尾所有空白字符
        \param[in,out]  s 原始字符串/Trim后字符串
        \see            Trim, TrimStart, TrimEnd, TrimStart_If, TrimEnd_If, Trim_If
        \note           空白字符包括 \\n \\r \\t \\v \\0 以及 空格
        \note           简便起见,此函数只实现了\a char 和 \a wchar 两个版本
    */
    template <typename CharT>
    void Trim(std::basic_string<CharT>& s);

    /*!
        \brief          和 Trim_Start() 功能类似,不过是否删除字符是由\a pred(c)指定的,如果其返回false,则结束Trim过程
        \param[in,out]  s 原始字符串/Trim后字符串
        \param[in]      pred 接收一个\a CharT 参数的谓词,如果认为该字符需要删除,返回true;反之,返回false
        \see            TrimStart, TrimEnd, TrimEnd_If, Trim, Trim_If
    */
    template <typename CharT, typename Predicate>
    void TrimStart_If(std::basic_string<CharT>& s, const Predicate& pred);

    /*!
        \brief          和 Trim_End() 功能类似,不过是否删除字符是由\a pred(c)指定的,如果其返回false,则结束Trim过程
        \param[in,out]  s 原始字符串/Trim后字符串
        \param[in]      pred 接收一个\a CharT 参数的谓词,如果认为该字符需要删除,返回true;反之,返回false
        \see            TrimStart, TrimEnd, TrimStart_If, Trim, Trim_If
    */
    template <typename CharT, typename Predicate>
    void TrimEnd_If(std::basic_string<CharT>& s, const Predicate& pred);

    /*!
        \brief          和 Trim() 功能类似,不过是否删除字符是由\a pred(c)指定的,如果其返回false,则结束Trim过程
        \param[in,out]  s 原始字符串/Trim后字符串
        \param[in]      pred 接收一个\a CharT 参数的谓词,如果认为该字符需要删除,返回true;反之,返回false
        \see            TrimStart, TrimEnd, TrimStart_If, Trim, Trim_If
    */
    template <typename CharT, typename Predicate>
    void Trim_If(std::basic_string<CharT>& s, const Predicate& pred);

#ifdef AC_RVALUE_REF
    template <typename CharT>
    std::basic_string<CharT> Lower(std::basic_string<CharT>&& s);

    template <typename CharT>
    std::basic_string<CharT> Upper(std::basic_string<CharT>&& s);
#endif // AC_RVALUE_REF
  }
}

#include "strutil_inl.h"

